#include "socket_stream.h"
#include <sys/socket.h>

namespace framework
{

SocketStream::SocketStream(Socket::ptr socket, bool owner)
:m_socket(socket)
,m_owner(owner)
{}

//如果m_owner=true,则close
SocketStream::~SocketStream()
{
    if(m_owner && m_socket)
    {
        m_socket->close();
    }
}

//返回是否连接
bool SocketStream::isConnected() const
{
    return m_socket && m_socket->isConnected();
}

//获取远端地址
Address::ptr SocketStream::getRemoteAddress() 
{
    if(m_socket) 
    {
        return m_socket->getRemoteAddress();
    }
    return nullptr;
}

//获取本地地址
Address::ptr SocketStream::getLocalAddress() 
{
    if(m_socket) 
    {
        return m_socket->getLocalAddress();
    }
    return nullptr;
}

//以字符串方式返回远端地址
std::string SocketStream::getRemoteAddressString() 
{
    auto addr = getRemoteAddress();
    if(addr) 
    {
        return addr->toString();
    }
    return "";
}

//以字符串方式返回本地地址
std::string SocketStream::getLocalAddressString() 
{
    auto addr = getLocalAddress();
    if(addr) 
    {
        return addr->toString();
    }
    return "";
}

//====================================================

//读数据
int SocketStream::read(void* buffer, size_t length)
{
    if(!isConnected())
    {
        return -1;
    }
    return m_socket->recv(buffer, length);
}

//读数据
int SocketStream::read(ByteArray::ptr ba, size_t length)
{
    if(!isConnected()) 
    {
        return -1;
    }
    std::vector<iovec> iovs;
    ba->getWriteBuffers(iovs, length);
    int rt = m_socket->recv(&iovs[0], iovs.size());
    if(rt > 0)
    {
        ba->setPosition(ba->getPosition() + rt);
    }
    return rt;
}

//写数据
int SocketStream::write(const void* buffer, size_t length)
{
    if(!isConnected())
    {
        return -1;
    }
    return m_socket->send(buffer, length);
}

//写数据
int SocketStream::write(ByteArray::ptr ba, size_t length)
{
    if(!isConnected())
    {
        return -1;
    }
    std::vector<iovec> iovs;
    ba->getReadBuffers(iovs, length);
    int rt = m_socket->send(&iovs[0], iovs.size());
    if(rt > 0)
    {
        ba->setPosition(ba->getPosition() + rt);
    }
    return rt;
}

//关闭流
void SocketStream::close()
{
    if(m_socket)
    {
        m_socket->close();
    }
}

}   //framework